package org.kth.dks;

import org.kth.dks.dks_comm.DKSRef;

/**
 * <p>Title: DKS</p>
 * <p>Description: DKS Middleware</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: KTH-IMIT/SICS</p>
 * @author not attributable
 * @version 1.0
 */

public interface DKSAppInterface {

  /**
   * Is set in DKSInterface through setCallbackHandler(). It is called at the responsible node when
   * a route() message reaches its destination. It receives a DKSObject, and returns a possibly new DKSObject
   * <b>INVARIANT</b>: the implementor of this method SHOULD immediately return, as otherwise the underlying DKSNode
   * cannot process new messagesl, and consequently the method cannot recursively call other methods in the DKSInterface
   * as the DKSNode will not be able to receive response messages. Consider using routeAsync() in DKSInterface.
   * @param identifier long, the identifier searched for in route, maybe not interesting for the app in many cases.
   * @param payload DKSObject, the actual payload sent by the source
   * @return DKSObject the payload to be routed back
   */
  public DKSObject routeCallback(long identifier, DKSObject payload);

  /**
   * Is set in DKSInterface through setCallbackHandler(). It is called at the responsible node when
   * a route() message reaches its destination.
   * as the DKSNode will not be able to receive response messages. Consider using routeAsync() in DKSInterface.
   * @param identifier long, the identifier searched for in route, maybe not interesting for the app in many cases.
   * @param payload DKSObject, the actual payload sent by the source
   * @return DKSObject the payload to be routed back
   */
  public void routeCallbackAsync(long identifier, DKSObject payload);


 /**
   * This callback routine is called when the node recieves a broadcast
   * message. Note that the sender of a broadcast also recieves a broadcast
   * msg.
   * @param payload DKSObject, the actual payload sent by the source
   */

 public void broadcastCallback(DKSObject payload);

  /**
   * This callback routine is called at the joining node, when the node is about to join
   * <b>INVARIANT:</b> this method must make a callback to DKSCallbacks.joinCallbackReturn
   * @param pred DKSRef predecessor reference, containing the identifier of the predecessor (useful for DHT impl)
   * @param succ DKSRef successor, containing the identifier of the successor (useful for DHT impl)
   */
  public void joinCallback(DKSRef pred, DKSRef succ);

  /**
   * This callback routine is called at the leaving node, when the node is about to leave
   * <b>INVARIANT:</b> this method must make a callback to DKSCallbacks.joinCallbackReturn
   * @param pred DKSRef predecessor reference, containing the identifier of the predecessor (useful for DHT impl)
   * @param succ DKSRef successor, containing the identifier of the successor (useful for DHT impl)
   */
  public void leaveCallback(DKSRef pred, DKSRef succ);

  /**
   * This callback routine is called at the successor of a filed node, when it detects its predecessor has failed.
   * @param failed DKSRef to the failed node (useful for DHT impl)
   * @param failedPred DKSRef to the failed nodes predecessor (useful for DHT impl)
   */
  public void failCallback(DKSRef failed, DKSRef failedPred);
  }
